
#include "common.h"
#include "resource.h"
#include "resmgr.h"
#include "uimgr.h"

//已删除部分注释

const int WinViewWidth=1080;
const int WinViewHeight=810;
const int UpdateTime=20;

HWND hWndMain;

GDirect2dManager* D2dMgr;
GResourceManager* ResMgr;
GUIManager* UiMgr;

void AppEntry();
void AppExit();

void OnWndCreate(HWND hWnd,LPVOID Param)
{
	hWndMain=hWnd;
	D2dMgr=new GDirect2dManager;
	D2dMgr->Init(hWnd,WinViewWidth,WinViewHeight);
	ResMgr=new GResourceManager;
	UiMgr=new GUIManager;
	UiMgr->LoadFixResource();
	//每秒50帧，不一定精确，差不多就行
	SetTimer(hWnd,1,UpdateTime,NULL);
	AppEntry();
}

void OnWndDestroy(HWND hWnd)
{
	AppExit();
	KillTimer(hWnd,1);
	//这里会销毁所有控件
	delete UiMgr;
	//这里会释放全部已经加载的资源
	delete ResMgr;
	D2dMgr->Uninit();
	delete D2dMgr;
}

void OnTimer(HWND hWnd,int TimerID)
{
	UiMgr->UpdateFrame();
}

void OnWndPaint(HDC hDC)
{
	UiMgr->UpdateView();
}

void OnWndActivate(HWND hWnd,BOOL Active)
{
	UiMgr->ResetInputState();
}

void OnWndResize(HWND hWnd,int Width,int Height,BOOL Minimized)
{
	UiMgr->ResizeView(Width,Height,Minimized);
}

void OnWndInput(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch (message)
	{
	case WM_LBUTTONDOWN:
		{
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			SetCapture(hWnd);
			UiMgr->DispatchInput(WM_LBUTTONDOWN,(PVOID)x,(PVOID)y);
		}
		break;
	case WM_LBUTTONUP:
		{
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			ReleaseCapture();
			UiMgr->DispatchInput(WM_LBUTTONUP,(PVOID)x,(PVOID)y);
		}
		break;
	case WM_MOUSEMOVE:
		{
			int x=(short)LOWORD(lParam);
			int y=(short)HIWORD(lParam);
			UiMgr->DispatchInput(WM_MOUSEMOVE,(PVOID)x,(PVOID)y);
		}
		break;
	case WM_MOUSEWHEEL:
		{
			int Value=(short)HIWORD(wParam)/WHEEL_DELTA;
			Value*=-1;	//UiMgr的定义正好与Windows相反
			UiMgr->DispatchInput(WM_MOUSEWHEEL,(PVOID)Value,(PVOID)0);
		}
		break;
	case WM_KEYDOWN:
		{
			UiMgr->DispatchInput(WM_KEYDOWN,(PVOID)wParam,(PVOID)0);
		}
		break;
	case WM_KEYUP:
		{
			UiMgr->DispatchInput(WM_KEYUP,(PVOID)wParam,(PVOID)0);
		}
		break;
	case WM_CHAR:
		{
			UiMgr->DispatchInput(WM_CHAR,(PVOID)wParam,(PVOID)0);
		}
		break;
	case WM_IME_STARTCOMPOSITION:
		{
			int x=0;
			int y=0;
			UiMgr->DispatchInput(WM_IME_STARTCOMPOSITION,(PVOID)&x,(PVOID)&y);
			SetImmBoxPosition(hWnd,x,y);
		}
		break;
	//使用WM_CHAR替代，否则不开输入法无法接收字符，开输入法后WM_CHAR重复接收字符
	case WM_IME_ENDCOMPOSITION:
		{
			WCHAR buf[100];
			int len=GetImmResultString(hWnd,buf,100);
			UiMgr->DispatchInput(WM_IME_ENDCOMPOSITION,(PVOID)buf,(PVOID)len);
		}
		break;
	}
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	switch (message)
	{
	case WM_CREATE:
		OnWndCreate(hWnd,((CREATESTRUCT*)lParam)->lpCreateParams);
		break;
	case WM_DESTROY:
		OnWndDestroy(hWnd);
		PostQuitMessage(0);
		break;
	case WM_TIMER:
		OnTimer(hWnd,wParam);
		break;
	case WM_PAINT:
		PAINTSTRUCT ps;
		BeginPaint(hWnd,&ps);
		OnWndPaint(ps.hdc);
		EndPaint(hWnd,&ps);
		break;
	case WM_ACTIVATE:
		OnWndActivate(hWnd,LOWORD(wParam));
		break;
	case WM_SIZE:
		OnWndResize(hWnd,LOWORD(lParam),HIWORD(lParam),wParam==SIZE_MINIMIZED);
		break;
	case WM_LBUTTONDOWN:
	case WM_LBUTTONUP:
	case WM_MOUSEMOVE:
	case WM_MOUSEWHEEL:
	case WM_KEYDOWN:
	case WM_KEYUP:
	case WM_CHAR:
		OnWndInput(hWnd,message,wParam,lParam);
		break;
	case WM_IME_STARTCOMPOSITION:
	//case WM_IME_ENDCOMPOSITION:
		OnWndInput(hWnd,message,wParam,lParam);
		return DefWindowProc(hWnd,message,wParam,lParam);
	default:
		return DefWindowProc(hWnd,message,wParam,lParam);
	}
	return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
	if (GetFileAttributes(L"EngineRes\\宋体-14.png")==0xFFFFFFFF ||
		GetFileAttributes(L"AppRes\\选择职业背景.jpg")==0xFFFFFFFF)
	{
		MessageBox(NULL,L"缺少资源文件！",L"提示",MB_OK|MB_ICONWARNING);
		return 0;
	}
    srand(GetTickCount()%971);
    
	WNDCLASSEX wcex;
	wcex.cbSize=sizeof(wcex);
	wcex.style=CS_HREDRAW|CS_VREDRAW;
	wcex.lpfnWndProc=WndProc;
	wcex.cbClsExtra=0;
	wcex.cbWndExtra=0;
	wcex.hInstance=hInstance;
	wcex.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_ICON1));
	wcex.hCursor=LoadCursor(NULL,IDC_ARROW);
	wcex.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName=NULL;
	wcex.lpszClassName=L"DnfCalcUI";
	wcex.hIconSm=NULL;
	RegisterClassEx(&wcex);

	RECT WinRect={0,0,WinViewWidth,WinViewHeight};
	DWORD WinStyle=WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX;
	AdjustWindowRectEx(&WinRect,WinStyle,FALSE,0);
	HWND hWndMain=CreateWindowEx(0,L"DnfCalcUI",L"炽天使计算器",WinStyle,
		0,0,WinRect.right-WinRect.left,WinRect.bottom-WinRect.top,NULL,NULL,NULL,NULL);
	ShowWindow(hWndMain,nShowCmd);
	UpdateWindow(hWndMain);

	MSG msg;
	while (GetMessage(&msg,NULL,0,0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return (int)msg.wParam;
}